import pygame
import random
from game_hud import *
from game_items import *
from game_music import *


class Game(object):
    
    """游戏类"""
    
    def __init__(self):
        self.main_window = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("飞机大战")
        self.is_game_over = False
        self.is_pause = False
        
        # 音乐
        # pygame.mixer.music.load("飞机大战001/res/sound/game_music.ogg")
        # pygame.mixer.music.play(-1)
        # hero_down_sound = pygame.mixer.Sound("飞机大战001/res/sound/me_down.wav")
        # hero_down_sound.play()

        # 精灵组属性
        self.all_group = pygame.sprite.Group()              # 11
        self.enemies_group = pygame.sprite.Group()          # 12
        self.supplies_group = pygame.sprite.Group()         # 13

        # 创建精灵
        # 14
        self.all_group.add(Background(False), Background(True))

        # HERO精灵，静止不动
        # hero = GameSprite("me1.png", 0, self.all_group)
        # self.hero = Plane(1000,5,0,"me_down.wav",
        #              ["me%d.png" % i for i in range(1,3)],
        #              "me1.png",
        #              ["me_destroy_%d.png" % i for i in range(1,5)],self.all_group)
        # self.hero.rect.center = SCREEN_RECT.center

        # 指示器面板
        self.hud_panel = HudPanel(self.all_group)
        
        # 创建敌机
        self.create_enemies()
        # 英雄精灵
        self.hero = Hero(self.all_group)
        # 设置面板中的炸弹数量
        self.hud_panel.show_bomb(self.hero.bomb_count)
        # 创建道具
        self.create_supplies()
        # 001
        self.player = MusicPlayer("game_music.ogg")
        self.player.play_music()

    def create_enemies(self):
        """根据游戏级别创建不同数量的敌机"""
        # 敌机精灵组的个数
        countd = len(self.enemies_group.sprites())
        # 要添加的精灵组
        groups = (self.all_group, self.enemies_group)
        # 判断。。。。。。。。。。
        if self.hud_panel.level == 1 and countd == 0:            # 111
            for i in range(16):
                Enemy(0, 3, *groups)
        elif self.hud_panel.level == 2 and countd == 16:         # 222
            print("升级到 %d" % self.hud_panel.level)
            print(countd)
            print("22222")
            # 增加速度
            for enemy in self.enemies_group.sprites():
                enemy.max_speed = 5
            # 创建敌机
            for i in range(8):
                Enemy(0, 5, *groups)
            for i in range(2):
                Enemy(1, 1, *groups)
                break
        elif self.hud_panel.level == 3 and countd == 25:
            print("升级到 %d" % self.hud_panel.level)
            print(countd)
            print("3333333")
            for enemy in self.enemies_group.sprites():
                enemy.max_speed = 7 if enemy.kind == 0 else 3
            for i in range(8):
                Enemy(0, 7, *groups)
            for i in range(2):
                Enemy(1, 3, *groups)
            for i in range(2):
                Enemy(2, 1, *groups)  

    def reset_game(self):
        """重置游戏"""
        self.is_game_over = False
        self.is_pause = False
        self.hud_panel.reset_panel()
        
        # 0000005
        self.hero.rect.midbottom = HERO_DEFAULT_MID_BOTTOM
        # 001
        for enemy in self.enemies_group:
            enemy.kill()
        # 002
        for bullet in self.hero.bullets_group:
            bullet.kill()
        # 003
        self.create_enemies()

    def event_handler(self):
        """事件监听
        :return:如果监听到退出事件,返回True,否则返回False
        """
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                if self.is_game_over:
                    self.reset_game()
                else:
                    self.is_pause = not self.is_pause       # 暂停状态
                    # 002
                    self.player.pause_music(self.is_pause)
                    
            # 判断是否正在游戏
            if not self.is_game_over and not self.is_pause:
                # 监听关闭子弹增强事件
                if event.type == BULLET_ENHANCED_OFF_EVENT:
                    self.hero.bullets_kind = 0
                    pygame.time.set_timer(BULLET_ENHANCED_OFF_EVENT,0)
                # 监听道具投放事件
                if event.type == THROW_SUPPLY_EVENT:
                    self.player.play_sound("supply.wav")
                    supply = random.choice(self.supplies_group.sprites())
                    supply.throw_supply()
                # 监听发射子弹
                if event.type == HERO_FIRE_EVENT:
                    self.player.play_sound("bullet.wav")
                    self.hero.fire(self.all_group)
                # 监听取消hero的无敌事件
                if event.type == HERO_POWER_OFF_EVENT:
                    print("hdbjhdgfah")
                    # 0002
                    self.hero.is_power = False
                    # 0003
                    pygame.time.set_timer(HERO_POWER_OFF_EVENT,0)
                # 001
                if event.type == HERO_DEAD_EVENT:
                    print("hahhahahha")
                    # 002
                    self.hud_panel.lives_count -= 1
                    # 003
                    self.hud_panel.show_lives()
                    # 004
                    self.hud_panel.show_bomb(self.hero.bomb_count)
                # 020
                if event.type == pygame.KEYDOWN and event.key == pygame.K_b:
                    # 00000000000000
                    if self.hero.hp > 0 and self.hero.bomb_count > 0:
                        self.player.play_sound("use_bomb.wav")
                    # for enemy in self.enemies_group.sprites():
                    #     enemy.hp = 0
                    # 001
                    score = self.hero.blowup(self.enemies_group)
                    # 003
                    self.hud_panel.show_bomb(self.hero.bomb_count)
                    # 002
                    if self.hud_panel.increase_score(score):
                        self.create_enemies()
        return False

    def start(self):
        """游戏开始"""
        clock = pygame.time.Clock()     # 游戏时钟
        frame_counter = 0                # 计时器
        while True:                     # 开始游戏循环
            # 000
            self.is_game_over = self.hud_panel.lives_count == 0
            if self.event_handler():    # 事件监听
                self.hud_panel.save_best_score()
                return
            # 判断游戏状态
            if self.is_game_over:
                # print("游戏已经结束,按空格重新开始.....")
                self.hud_panel.panel_pause(True,self.all_group)
            elif self.is_pause:
                # print("游戏已经暂停,按空格键继续....")
                self.hud_panel.panel_pause(False,self.all_group)
            else:
                # print("游戏进行中....")
                self.hud_panel.panel_resume(self.all_group)
                # 碰撞检测
                self.check_collide()
                # 修改游戏得分
                # if self.hud_panel.increase_score(10):
                #     print("升级到 %d" % self.hud_panel.level)
                #     self.create_enemies() 
                # 模拟英雄飞机受伤
                # self.hero.hp -= 30
                # ****************获得当前时刻的按键元素
                keys = pygame.key.get_pressed()
                # 水平移动001
                move_hor = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
                # 垂直移动001
                move_vor = keys[pygame.K_DOWN] - keys[pygame.K_UP]
                # 逐帧动画计数器
                frame_counter = (frame_counter + 1) % FRAME_INTERVAL
                # 更新 all_group.update(),更新所有精灵
                self.all_group.update(frame_counter == 0, move_hor, move_vor)
            # 绘制 all_group 中所有的精灵
            self.all_group.draw(self.main_window)
            pygame.display.update()     # 更新显示
            clock.tick(60)              # 设置刷新率

    def check_collide(self):
        global enemies
        """碰撞检测"""
        # 检测英雄飞机和敌机的碰撞 - 如果英雄飞机处于无敌状态，彼此不能碰撞
        if not self.hero.is_power:
            enemies = pygame.sprite.spritecollide(self.hero,
                                                  self.enemies_group,
                                                  False,
                                                  pygame.sprite.collide_mask)
            # 过滤掉已经被摧毁的敌机
            enemies = list(filter(lambda x: x.hp > 0, enemies))
            # 是否撞到敌机
            if enemies:
                self.player.play_sound(self.hero.wav_name)
                self.hero.hp = 0                # 001
            for enemy in enemies:
                enemy.hp = 0                    # 摧毁发生碰撞的敌机
            
        # 检测敌机被子弹集中
        hit_enemies = pygame.sprite.groupcollide(self.enemies_group,
                                                 self.hero.bullets_group,
                                                 False,
                                                 False,
                                                 pygame.sprite.collide_mask)
        # 001
        for enemy in hit_enemies:
            if enemy.hp <= 0:
                continue
            
            for bullet in hit_enemies[enemy]:
                bullet.kill()
                enemy.hp -= bullet.damage
                if enemy.hp > 0:
                    continue
                if self.hud_panel.increase_score(enemy.value):
                    self.player.play_sound("upgrade.wav")
                    self.create_enemies()
                self.player.play_sound(enemy.wav_name)
                break
        # 1001011
        supplies = pygame.sprite.spritecollide(self.hero,
                                               self.supplies_group,
                                               False,
                                               pygame.sprite.collide_mask)
        if supplies:
            supply = supplies[0]
            self.player.play_sound(supply.wav_name)
            supply.rect.y = SCREEN_RECT.h
            if supply.kind == 0:
                self.hero.bomb_count += 1
                self.hud_panel.show_bomb(self.hero.bomb_count)
            else:
                self.hero.bullets_kind = 1
                pygame.time.set_timer(BULLET_ENHANCED_OFF_EVENT,80000)
                
    def create_supplies(self):
        """创建道具"""
        Supply(0,self.supplies_group, self.all_group)
        Supply(1,self.supplies_group, self.all_group)
        pygame.time.set_timer(THROW_SUPPLY_EVENT,10000)


if __name__ == "__main__":
    pygame.init()
    Game().start()
    pygame.quit()
